package com.flkin.security;

import com.flkin.common.annotation.AnonymousAccess;
import com.flkin.common.base.Ret;
import com.flkin.common.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yanxiang.huang
 */
@Slf4j
@RestController
@RequestMapping("/auth")
public class IAuthController {

    @Resource
    private TokenProvider tokenProvider;
    @Resource
    private AuthenticationManagerBuilder authenticationManagerBuilder;
    @Resource
    private SecurityProperties properties;
    @Resource
    private RedisUtils redisUtils;

    /**
     * 用户名，密码登录入口
     * @param authBody authBody
     * @return authInfo
     */
    @AnonymousAccess
    @PostMapping(value = "/login")
    public ResponseEntity<Object> login(@RequestBody IAuthBody authBody) {
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(authBody.getUsername(), authBody.getPassword());
        Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = tokenProvider.createToken(authentication);
        IUserDetails userDetails = (IUserDetails) authentication.getPrincipal();
        redisUtils.set(RedisUtils.TOKEN_KEY + token, userDetails, properties.getTokenExpireSeconds());
        Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
            put("token", properties.getTokenStartWith() + token);
            put("info", userDetails);
        }};
        return ResponseEntity.ok(Ret.builder().data(authInfo).build());
    }

    @AnonymousAccess
    @GetMapping(value = "/logout")
    public ResponseEntity<Object> logout(HttpServletRequest request) {
        String token = tokenProvider.getToken(request);
        if (token != null) {
            redisUtils.del(RedisUtils.TOKEN_KEY + token);
        }
        return ResponseEntity.ok(Ret.builder().code(1001).build());
    }

}
